using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using xn;

namespace StartDance
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class PlayerManager : Microsoft.Xna.Framework.GameComponent
    {
        Game thisgame;
        Context context;
        UserGenerator userGenerator;
        GestureGenerator gestureGenerator;

        public Texture2D picture;
        public List<Player> playerList;

        Delegate gestureHandler;

        public PlayerManager(Game game, Delegate _gestureHandler)
            : base(game)
        {
            thisgame = game;
            gestureHandler = _gestureHandler;
            try
            {
                context = new Context("openni.xml");

                userGenerator = new UserGenerator(context);
                userGenerator.NewUser += new UserGenerator.NewUserHandler(userGenerator_NewUser);
                userGenerator.LostUser += new UserGenerator.LostUserHandler(userGenerator_LostUser);
                gestureGenerator = new GestureGenerator(context);
                gestureGenerator.AddGesture("Wave");
                gestureGenerator.GestureRecognized += new GestureGenerator.GestureRecognizedHandler(gestureGenerator_GestureRecognized);
                context.StartGeneratingAll();
                
                playerList = new List<Player>();

                Initialize();
            }
            catch (Exception ex)
            {
                game.Dispose();
                game.Exit();
                System.Windows.Forms.MessageBox.Show("Program tidak berhasil dijalankan. Penyebab : " + ex.Message);
            }
        }

        void gestureGenerator_GestureRecognized(ProductionNode node, string strGesture, ref Point3D idPosition, ref Point3D endPosition)
        {
            if (strGesture == "Wave")
            {
                gestureHandler.DynamicInvoke();
            }
        }

        void userGenerator_NewUser(ProductionNode node, uint id)
        {
            Player player = new Player(id);
            playerList.Add(player);
            Console.WriteLine("New User : " + id);
            //throw new NotImplementedException();
        }

        void userGenerator_LostUser(ProductionNode node, uint id)
        {
            Player player = playerList.Find(a=>a.uid==id);
            playerList.Remove(player);
            Console.WriteLine("Lost User : " + id);
            //throw new NotImplementedException();
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {

            // TODO: Add your initialization code here
            picture = thisgame.Content.Load<Texture2D>(@"image/player");
            base.Initialize();
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            // TODO: Add your update code here
            try
            {
                if (context != null)
                {
                    context.WaitNoneUpdateAll();
                    foreach (Player player in playerList)
                    {
                        player.position = userGenerator.GetCoM(player.uid);
                    }
                }
            }
            catch{};
            base.Update(gameTime);
        }
    }
}